import { FormattedKlineData } from '../../services/market-data.service';
import { IndicatorsService } from '../../services/indicators.service';
import { TAKlineData } from '../../types/indicator.types';
import { BaseStrategy, BaseStrategyConfig, PositionState, TradeSignal } from '../strategy.interface';

/**
 * DualMovingAverageStrategy 的特定配置接口
 */
export interface DualMAStrategyConfig extends BaseStrategyConfig {
  shortPeriod: number;
  longPeriod: number;
}

/**
 * 双移动平均线交叉策略
 * 
 * 该策略继承自 BaseStrategy，专注于实现其核心的交易逻辑：
 * - 当短期均线上穿长期均线时（黄金交叉），开多仓或买入。
 * - 当短期均线下穿长期均线时（死亡交叉），开空仓或卖出。
 * 
 * 所有的止损逻辑和状态管理都由父类 BaseStrategy 处理。
 */
export class DualMovingAverageStrategy extends BaseStrategy {
  public name: string;
  public readonly warmupPeriod: number;

  private readonly shortPeriod: number;
  private readonly longPeriod: number;

  // 指标数据
  private shortMaValues: Map<number, number> = new Map();
  private longMaValues: Map<number, number> = new Map();
  private prevShortMa: number | null = null;
  private prevLongMa: number | null = null;

  constructor(config: DualMAStrategyConfig) {
    super(config); // 调用父类的构造函数
    this.shortPeriod = config.shortPeriod;
    this.longPeriod = config.longPeriod;

    const mode = this.accountType === 'spot' ? 'Spot' : 'Contract';
    this.name = `Dual MA Crossover [${mode}] (${this.shortPeriod}/${this.longPeriod})`;
    this.warmupPeriod = Math.ceil(this.longPeriod * 1.5);
    console.log(`Strategy created: ${this.name}. Requires ${this.warmupPeriod} warm-up periods.`);
  }

  /**
   * 初始化指标
   */
  public async initialize(data: FormattedKlineData[]): Promise<void> {
    console.log(`Calculating indicators for ${this.name}...`);
    const indicatorsService = new IndicatorsService();
    const taKlines: TAKlineData[] = data.map(k => ({
      timestamp: k.timestamp,
      open: k.open,
      high: k.high,
      low: k.low,
      close: k.close,
      volume: k.volume,
    }));

    const shortMaResults = indicatorsService.calculateSMA(taKlines, { period: this.shortPeriod });
    shortMaResults.forEach(r => this.shortMaValues.set(r.timestamp as number, r.value));

    const longMaResults = indicatorsService.calculateSMA(taKlines, { period: this.longPeriod });
    longMaResults.forEach(r => this.longMaValues.set(r.timestamp as number, r.value));

    console.log(`Indicators calculated. Short MA: ${this.shortMaValues.size}, Long MA: ${this.longMaValues.size}`);
  }

  /**
   * 策略的核心更新逻辑
   */
  public update(kline: FormattedKlineData): TradeSignal {
    // 1. 优先检查止损，这是由 BaseStrategy 提供的通用功能
    const stopLossSignal = this.checkStopLoss(kline);
    if (stopLossSignal !== TradeSignal.HOLD) {
      return stopLossSignal;
    }

    // 2. 获取当前周期的指标数据
    const shortMa = this.shortMaValues.get(kline.timestamp);
    const longMa = this.longMaValues.get(kline.timestamp);

    if (shortMa === undefined || longMa === undefined || this.prevShortMa === null || this.prevLongMa === null) {
      if (shortMa !== undefined) this.prevShortMa = shortMa;
      if (longMa !== undefined) this.prevLongMa = longMa;
      return TradeSignal.HOLD;
    }

    // 3. 判断交易信号（金叉/死叉）
    const isGoldenCross = this.prevShortMa <= this.prevLongMa && shortMa > longMa;
    const isDeathCross = this.prevShortMa >= this.prevLongMa && shortMa < longMa;

    this.prevShortMa = shortMa;
    this.prevLongMa = longMa;

    // 4. 根据账户类型（现货/合约）执行不同的逻辑
    if (this.accountType === 'contract') {
      return this.updateContract(isGoldenCross, isDeathCross, kline);
    } else {
      return this.updateSpot(isGoldenCross, isDeathCross, kline);
    }
  }

  /**
   * 现货模式的信号生成逻辑
   */
  private updateSpot(isGoldenCross: boolean, isDeathCross: boolean, kline: FormattedKlineData): TradeSignal {
    if (isGoldenCross && this.spotLastSignal !== TradeSignal.BUY) {
      this.spotLastSignal = TradeSignal.BUY;
      this.entryPrice = kline.close;
      this.stopLossPrice = this.entryPrice * (1 - this.stopLossRate);
      return TradeSignal.BUY;
    }

    if (isDeathCross && this.spotLastSignal === TradeSignal.BUY) {
      this.spotLastSignal = TradeSignal.SELL;
      this.entryPrice = null;
      this.stopLossPrice = null;
      return TradeSignal.SELL;
    }

    return TradeSignal.HOLD;
  }

  /**
   * 合约模式的信号生成逻辑
   */
  private updateContract(isGoldenCross: boolean, isDeathCross: boolean, kline: FormattedKlineData): TradeSignal {
    if (isGoldenCross && this.contractState !== PositionState.LONG) {
      this.contractState = PositionState.LONG;
      this.entryPrice = kline.close;
      this.stopLossPrice = this.calcContractStopLossPrice(this.entryPrice, PositionState.LONG);
      return TradeSignal.OPEN_LONG;
    }

    if (isDeathCross && this.contractState !== PositionState.SHORT) {
      this.contractState = PositionState.SHORT;
      this.entryPrice = kline.close;
      this.stopLossPrice = this.calcContractStopLossPrice(this.entryPrice, PositionState.SHORT);
      return TradeSignal.OPEN_SHORT;
    }

    return TradeSignal.HOLD;
  }
}
